home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / lib / ImpExp3ds / 3dsImport.cpp < prev   
Encoding:
C/C++ Source or Header  |  2000-02-02  |  9.1 KB  |  428 lines

  1. #include "../Fly3D.h"
  2.  
  3. int import3ds::read_chunk()
  4. {
  5.     int i=0;
  6.  
  7.     i+=fp.read(&chunkid, 2);//fread(&chunkid,1,2,fp);
  8.     i+=fp.read(&chunklen, 4);//fread(&chunklen,1,4,fp);
  9.     if (i!=6)
  10.         return 0;
  11.     if (chunklen>6)
  12.         chunklen-=6;
  13.     filepos+=6;
  14.     
  15.     return 1;
  16. }
  17.  
  18. void import3ds::jump_chunk()
  19. {
  20.     fp.seek(chunklen);//fseek(fp,chunklen,SEEK_CUR);
  21.     filepos+=chunklen;
  22. }
  23.  
  24. void import3ds::load_chunk()
  25. {
  26.     if (chunk)
  27.         delete chunk;
  28.     chunk=new char[chunklen];
  29.     filepos+=chunklen;
  30.     fp.read(chunk, chunklen);//fread(chunk,chunklen,1,fp);
  31. }
  32.  
  33. void import3ds::load_string(char *str)
  34. {
  35.     int a=0;
  36.  
  37.     while( (fp.read(&str[a],1)==1) && str[a++] );
  38.  
  39.     chunklen-=a;
  40.     filepos+=a;
  41. }
  42.  
  43. void import3ds::load_object()
  44. {
  45.     char objname[256];
  46.  
  47.     load_string(objname);
  48.     read_chunk();
  49.     switch(chunkid)
  50.     {
  51.         case 0x4600:
  52.         {
  53.             load_light(objname);
  54.             break;
  55.         }
  56.         case 0x4700:
  57.         {
  58.             load_chunk();
  59.             camera(objname, (float *)chunk,(float *)&chunk[12], *((float *)&chunk[24]), *((float *)&chunk[28]));
  60.             break;
  61.         }
  62.         case 0x4100:
  63.         {
  64.             if (object_name(objname))
  65.                 load_mesh(objname);
  66.             else jump_chunk();
  67.             break;
  68.         }
  69.         default:
  70.             jump_chunk();
  71.     }
  72. }
  73.  
  74. void import3ds::load_mesh(char *objname)
  75. {
  76.     int nvert=0,nfaces=0,ntextcoord=0,nfacematerial=0;
  77.     char *vert=0,*faces=0,*textcoord=0,*facematerial=0;
  78.     float local_axis[12]={ 1,0,0, 0,1,0, 0,0,1, 0,0,0 };
  79.     int a,fpos=filepos+chunklen;
  80.     while( filepos<fpos)
  81.     {
  82.         read_chunk();
  83.         switch(chunkid)
  84.         {
  85.         case 0x4110:
  86.             {
  87.             load_chunk();
  88.             nvert=*((unsigned short *)chunk);
  89.             vert=chunk;
  90.             chunk=0;
  91.             break;
  92.             }
  93.         case 0x4120:
  94.             {
  95.             int fpos2=filepos+chunklen;
  96.             fp.read(&nfaces, 2);//fread(&nfaces,2,1,fp);
  97.             faces=new char[nfaces*2*4+2];
  98.             fp.read(&faces[2], nfaces*2*4);//fread(&faces[2],nfaces*2,4,fp);
  99.             filepos+=nfaces*2*4+2;
  100.             *((unsigned short *)faces)=nfaces;
  101.             while( filepos<fpos2)
  102.                 {
  103.                 read_chunk();
  104.                 switch(chunkid)
  105.                     {
  106.                     case 0x4130:
  107.                         {
  108.                         load_chunk();
  109.                         if (nfacematerial==0)
  110.                             {
  111.                             facematerial=chunk;
  112.                             chunk=0;
  113.                             nfacematerial=chunklen;
  114.                             }
  115.                         else 
  116.                             {
  117.                             char *temp=new char[nfacematerial+chunklen];
  118.                             memcpy(temp,facematerial,nfacematerial);
  119.                             memcpy(&temp[nfacematerial],chunk,chunklen);
  120.                             delete facematerial;
  121.                             facematerial=temp;
  122.                             nfacematerial+=chunklen;
  123.                             }
  124.                         break;
  125.                         }
  126.                     default: jump_chunk();
  127.                     }
  128.                 }
  129.             break;
  130.             }
  131.         case 0x4140:
  132.             {
  133.             load_chunk();
  134.             ntextcoord=*((unsigned short *)chunk);
  135.             textcoord=chunk;
  136.             chunk=0;
  137.             }
  138.             break;
  139.         case 0x4160:
  140.             {
  141.             load_chunk();
  142.             memcpy(local_axis,chunk,sizeof(float)*12);
  143.             }
  144.             break;
  145.         default:
  146.             jump_chunk();
  147.         }
  148.     }
  149.     if (nvert!=0 && nfaces!=0)
  150.     {
  151.     local_axis[9]*=masterscale*scale;
  152.     local_axis[10]*=masterscale*scale;
  153.     local_axis[11]*=masterscale*scale;
  154.  
  155.     object3d(objname,nvert,nfaces,ntextcoord,local_axis);
  156.     
  157.     for( a=0;a<nvert;a++ )
  158.     {
  159.         float *f=(float *)(2+vert+a*12);
  160.         f[0]*=masterscale*scale;
  161.         f[1]*=masterscale*scale;
  162.         f[2]*=masterscale*scale;
  163.         vertex3(f);
  164.     }
  165.     
  166.     for( a=0;a<ntextcoord;a++ )
  167.     {
  168.         *((float *)(6+textcoord+a*8))*=-1;
  169.         text_coord((float *)(2+textcoord+a*8));
  170.     }
  171.  
  172.     for( a=0;a<nfaces;a++ )
  173.         face3((unsigned short *)(2+faces+a*8));
  174.  
  175.     a=0;
  176.     int b,c,len;
  177.     while( a<nfacematerial )
  178.         {
  179.         for( b=0;b<nmat;b++ )
  180.             if (!stricmp(matlib[b].name,&facematerial[a]))
  181.                 break;
  182.         c=strlen(&facematerial[a]);
  183.         len=*((unsigned short *)&facematerial[a+c+1]);
  184.         if (b<nmat)
  185.             face_material(&matlib[b],len,(unsigned short *)&facematerial[a+c+3]);
  186.         a+=len*2+c+3;
  187.         }
  188.     }
  189.     if (vert)
  190.         delete vert;
  191.     if (faces)
  192.         delete faces;
  193.     if (facematerial)
  194.         delete facematerial;
  195.     if (textcoord)
  196.         delete textcoord;
  197. }
  198.  
  199. void import3ds::load_light(char *objname)
  200. {
  201.     float pos[3],target[3],color[3],hotspot,falloff;
  202.     int type=0;
  203.     int fpos=filepos+chunklen;
  204.     fp.read(pos,12);//fread(pos,12,1,fp);
  205.     filepos+=12;
  206.     while( filepos<fpos )
  207.     {
  208.         read_chunk();
  209.         switch(chunkid)
  210.         {
  211.             case 0x0010:
  212.                 load_chunk();
  213.                 color[0]=*((float *)&chunk[0]);
  214.                 color[1]=*((float *)&chunk[4]);
  215.                 color[2]=*((float *)&chunk[8]);
  216.                 break;
  217.             case 0x0011:
  218.                 load_chunk();
  219.                 color[0]=(float)(((unsigned char)chunk[0])/255.0);
  220.                 color[1]=(float)(((unsigned char)chunk[1])/255.0);
  221.                 color[2]=(float)(((unsigned char)chunk[2])/255.0);
  222.                 break;
  223.             case 0x4610:
  224.                 load_chunk();
  225.                 target[0]=*((float *)&chunk[0]);
  226.                 target[1]=*((float *)&chunk[4]);
  227.                 target[2]=*((float *)&chunk[8]);
  228.                 hotspot=*((float *)&chunk[12]);
  229.                 falloff=*((float *)&chunk[16]);
  230.                 type=1;
  231.                 break;
  232.  
  233.             default:
  234.                 jump_chunk();
  235.         }
  236.     }
  237.     if (type)
  238.         spotlight(objname, pos, target, color, hotspot, falloff);
  239.     else pointlight(objname, pos, color);
  240. }
  241.  
  242. int import3ds::import(char *name,float scalefactor)
  243. {
  244.     scale=scalefactor;
  245.     //fp=fopen(name,"rb");
  246.     if (!fp.open(name))
  247.         return 0;
  248.  
  249.     while(read_chunk())
  250.         switch(chunkid)
  251.         {
  252.         case M3DMAGIC:
  253.         case MDATA:
  254.             break;
  255.         case MASTER_SCALE:
  256.             {
  257.             load_chunk();
  258.             masterscale=*((float *)chunk);
  259.             }
  260.             break;
  261.         case NAMED_OBJECT:
  262.             load_object();
  263.             break;
  264.         case MAT_ENTRY:
  265.             load_material();
  266.             matlib[nmat-1].ambient[3]=matlib[nmat-1].transparency;
  267.             matlib[nmat-1].diffuse[3]=matlib[nmat-1].transparency;
  268.             matlib[nmat-1].specular[3]=matlib[nmat-1].transparency;
  269.             break;
  270.         default:
  271.             jump_chunk();
  272.         }
  273.  
  274.     fp.close();//fclose(fp);
  275.     return 1;
  276. }
  277.  
  278. void import3ds::load_mapping(struct mapping *m)
  279. {
  280.     int fpos=filepos+chunklen;
  281.  
  282.     m->u_scale=1.0;
  283.     m->v_scale=1.0;
  284.     m->u_offset=0.0;
  285.     m->v_offset=0.0;
  286.     m->rotation=0.0;
  287.  
  288.     while( filepos<fpos )
  289.     {
  290.         read_chunk();
  291.         switch(chunkid)
  292.         {
  293.         case 0x0030:
  294.             load_chunk();
  295.             m->amount=*((short int *)chunk);
  296.             break;
  297.         case 0xA300:
  298.             load_string(m->filename);
  299.             break;
  300.         case 0xA351:
  301.             load_chunk();
  302.             m->options=*((short int *)chunk);
  303.             break;
  304.         case 0xA353:
  305.             load_chunk();
  306.             m->filtering=*((float *)chunk);
  307.             break;
  308.         case 0xA354:
  309.             load_chunk();
  310.             m->u_scale=*((float *)chunk);
  311.             break;
  312.         case 0xA356:
  313.             load_chunk();
  314.             m->v_scale=*((float *)chunk);
  315.             break;
  316.         case 0xA358:
  317.             load_chunk();
  318.             m->u_offset=*((float *)chunk);
  319.             break;
  320.         case 0xA35A:
  321.             load_chunk();
  322.             m->v_offset=*((float *)chunk);
  323.             break;
  324.         case 0xA35C:
  325.             load_chunk();
  326.             m->rotation=*((float *)chunk);
  327.             break;
  328.         default:
  329.             jump_chunk();
  330.         }
  331.     }
  332. }
  333.  
  334. void import3ds::load_material()
  335. {
  336.     int fpos=filepos+chunklen;
  337.     while( filepos<fpos )
  338.     {
  339.         read_chunk();
  340.         switch(chunkid)
  341.         {
  342.             case 0xA000:
  343.                 if (matlib)
  344.                     {
  345.                     material *temp=new material[nmat+1];
  346.                     memcpy(temp,matlib,sizeof(material)*nmat);
  347.                     delete matlib;
  348.                     matlib=temp;
  349.                     } else matlib=new material;
  350.                 load_string(matlib[nmat].name);
  351.                 nmat++;
  352.                 break;
  353.             case 0xA010:
  354.                 load_chunk();
  355.                 matlib[nmat-1].ambient[0]=(float)(((unsigned char)chunk[6])/255.0);
  356.                 matlib[nmat-1].ambient[1]=(float)(((unsigned char)chunk[7])/255.0);
  357.                 matlib[nmat-1].ambient[2]=(float)(((unsigned char)chunk[8])/255.0);
  358.                 break;
  359.             case 0xA020:
  360.                 load_chunk();
  361.                 matlib[nmat-1].diffuse[0]=(float)(((unsigned char)chunk[6])/255.0);
  362.                 matlib[nmat-1].diffuse[1]=(float)(((unsigned char)chunk[7])/255.0);
  363.                 matlib[nmat-1].diffuse[2]=(float)(((unsigned char)chunk[8])/255.0);
  364.                 break;
  365.             case 0xA030:
  366.                 load_chunk();
  367.                 matlib[nmat-1].specular[0]=(float)(((unsigned char)chunk[6])/255.0);
  368.                 matlib[nmat-1].specular[1]=(float)(((unsigned char)chunk[7])/255.0);
  369.                 matlib[nmat-1].specular[2]=(float)(((unsigned char)chunk[8])/255.0);
  370.                 break;
  371.             case 0xA040:
  372.                 load_chunk();
  373.                 matlib[nmat-1].shininess=(float)(((unsigned char)chunk[6])/100.0);
  374.                 break;
  375.             case 0xA041:
  376.                 load_chunk();
  377.                 matlib[nmat-1].shininess_strength=(float)(((unsigned char)chunk[6])/100.0);
  378.                 break;
  379.             case 0xA050:
  380.                 load_chunk();
  381.                 matlib[nmat-1].transparency=(float)(((unsigned char)chunk[6])/100.0);
  382.                 break;
  383.             case 0xA052:
  384.                 load_chunk();
  385.                 matlib[nmat-1].transparency_falloff=(float)(((unsigned char)chunk[6])/100.0);
  386.                 break;
  387.             case 0xA053:
  388.                 load_chunk();
  389.                 matlib[nmat-1].reflect_blur=(float)(((unsigned char)chunk[6])/100.0);
  390.                 break;
  391.             case 0xA100:
  392.                 load_chunk();
  393.                 matlib[nmat-1].material_type=*((short *)chunk);
  394.                 break;
  395.             case 0xA084:
  396.                 load_chunk();
  397.                 matlib[nmat-1].self_illum=(float)(((unsigned char)chunk[6])/100.0);
  398.                 break;
  399.             case 0xA200:
  400.                 load_mapping(&matlib[nmat-1].map_texture1);
  401.                 break;
  402.             case 0xA33A:
  403.                 load_mapping(&matlib[nmat-1].map_texture2);
  404.                 break;
  405.             case 0xA210:
  406.                 load_mapping(&matlib[nmat-1].map_opacity);
  407.                 break;
  408.             case 0xA230:
  409.                 load_mapping(&matlib[nmat-1].map_bump);
  410.                 break;
  411.             case 0xA204:
  412.                 load_mapping(&matlib[nmat-1].map_specular);
  413.                 break;
  414.             case 0xA33C:
  415.                 load_mapping(&matlib[nmat-1].map_shininess);
  416.                 break;
  417.             case 0xA33D:
  418.                 load_mapping(&matlib[nmat-1].map_selfillum);
  419.                 break;
  420.             case 0xA220:
  421.                 load_mapping(&matlib[nmat-1].map_reflection);
  422.                 break;
  423.             default:
  424.                 jump_chunk();
  425.         }
  426.     }
  427. }
  428.